#pragma once

#include <memory>
#include <cstdlib>

#include "./TestSetBase.h"

namespace ceph_mock {
class Objecter;
}   /* namespace ceph_mock */


struct PMKVTestSetBase : TestSetBase {
    /** all test cases share this same Objecter instance */
    std::unique_ptr<ceph_mock::Objecter> objecter = nullptr;
    const std::string rpmkv_path;

    explicit PMKVTestSetBase(string_view name, string_view rpmkv_path)
        : TestSetBase(name), rpmkv_path(rpmkv_path)
    {
        this->objecter = make_unique<ceph_mock::Objecter>();
        assert(this->objecter);
        this->objecter->rpmkv = make_unique<PMKV::PMEMDevice>(rpmkv_path.data());
        assert(this->objecter->rpmkv);
    }

    /* helper functions */

    /**
     * remove all key-value entries in PMKV
     */
    void clean_all()
    {
        this->objecter->rpmkv.reset();
        int rc;
        if (rc = system(("pmempool rm "s + rpmkv_path).c_str()))
            throw std::runtime_error("failed to remove poolset: "s + std::strerror(rc));
        system("sleep 1");
        if (rc = system(("pmempool create obj --layout=PMEMDevice "s + rpmkv_path).c_str()))
            throw std::runtime_error("failed to create obj pool: "s + std::strerror(rc));
        this->objecter->rpmkv = make_unique<PMKV::PMEMDevice>(rpmkv_path.data());
        assert(this->objecter->rpmkv);
    }
};  /* struct PMKVTestSetBase */
